<template>
  <div class="input-upload" @click="doFileUpload">
    <input
      ref="file"
      type="file"
      :accept="accept"
      name="file"
      class="formFile"
      @change="fileChange"
    />
    <div v-if="value" class="content" flex="cross:center box:last">
      <div class="w100 fcc">
        <i class="el-icon-paperclip mr8"></i>
        <span class="name ellipsis">{{ fileName }}</span>
      </div>
      <i v-if="!disabled" class="el-icon-close" @click.stop="doDel"></i>
    </div>
    <div v-else class="placeholder default-wrap ftcc">
      <slot name="default">
        <!-- <div>{{ disabled ? "" : placeholder }}</div> -->
        <i v-if="!disabled" class="el-icon-upload fz26 primary"></i>
      </slot>
    </div>
    <transition name="el-fade-in-linear">
      <div v-if="uploading" class="process-wrapper">
        <el-progress :percentage="percentage" :stroke-width="4" class="mt8 mb10" />
      </div>
    </transition>
  </div>
</template>

<script>
import { FileUpload } from "api/sys/file";
import emitter from "element-ui/src/mixins/emitter";

export default {
  mixins: [emitter],
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    accept: {
      type: String,
      default: "*",
    },
    value: String,
    placeholder: {
      type: String,
      default: "请上传文件",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    // 最大尺寸
    maxSize: {
      type: Number,
      default: 0,
    },
    // 最大尺寸单位
    unit: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ["M", "KB"].indexOf(value) !== -1;
      },
    },
  },
  data() {
    return {
      // 文件正在上传
      uploading: false,
      // 上传进度
      percentage: 0,
    };
  },
  computed: {
    fileName() {
      return !this.value ? "" : this.$getFileName(this.value);
    },
  },
  watch: {
    value(val) {
      this.dispatch("ElFormItem", "el.form.change", val);
    },
  },
  methods: {
    /**
     * 开始文件选择
     */
    doFileUpload() {
      if (this.disabled) {
        if (!this.value) return;
        location.href = this.value;
      } else {
        !this.uploading && this.$refs.file.click();
      }
    },
    /**
     * 文件上传
     */
    async fileChange(event) {
      try {
        this.uploading = true;
        const uploadFile = event.target.files[0];
        if (this.maxSize) {
          const { size } = uploadFile;
          this.maxSizeValidate(size);
        }
        let formData = new FormData();
        formData.append("file", uploadFile);
        const { savePath } = await FileUpload(formData, {
          onUploadProgress: this.onUploadProgress,
        });
        event.target.value = "";
        this.$emit("change", savePath);
      } catch (e) {
        this.$message.error(e.message);
        event.target.value = "";
      } finally {
        this.uploading = false;
        this.percentage = 0;
      }
    },
    /**
     * 文件上传最大尺寸校验
     */
    maxSizeValidate(size) {
      let num = this.maxSize * 1024;
      if (this.unit === "M") {
        num *= 1024;
      }
      if (size > num) {
        throw new Error(`文件最大不能超过${this.maxSize}${this.unit}`);
      }
    },
    /**
     * 上传进度
     */
    onUploadProgress(e) {
      const { loaded, total } = e;
      this.percentage = parseInt((loaded / total) * 100);
    },
    /**
     * 删除
     */
    doDel() {
      this.$emit("change", "");
    },
  },
};
</script>

<style lang="scss" scoped>
.input-upload {
  width: 100%;
  border-radius: 4px;
  position: relative;
  height: 36px;
  line-height: 1;
  cursor: pointer;
  .process-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background: rgba(255, 255, 255, 0.7);
    z-index: 1;
  }
  // 美化按钮样式
  .formFile {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    overflow: hidden;
    position: absolute;
    z-index: -1;
  }
  .content {
    height: 100%;
    padding: 0 2px;
  }
  .default-wrap {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }
}
</style>
